/* 
* sepstrct.h - This file is a part of the sep-library 
*
* Copyright (C) 2008 Jesper Schmidt Hansen 
* 
* License: GPL - see COPYING for copying conditions.
* There is ABSOLUTELY NO WARRANTY, not even for MERCHANTIBILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* Contact: schmidt@zigzak.net
*/


#ifndef __SEPSTRCT_H__
#define __SEPSTRCT_H__

#include "sepdef.h"

/**
 * The seppart structure - containing all relevant 
 * information about the particle such as position mass etc.
 */
typedef struct {
  double x[3];          /**< Position */
  double v[3];          /**< Velocity */
  double f[3];          /**< Force */
  double a[3];          /**< Acceleration */  
  double m;             /**< Mass */
  char type;            /**< Particle type */
  double z;             /**< Point charge */

  int *neighb;          /**< Neighbour list */

  int cross_neighb[3];     /**< Boundary crossings - for auto neighb update */
  int crossings[3];   /**< Boundary crossings (not reset after neighb list update)*/

  int molindex;         /**< Molecule index (what molecule does this atom belong to) */  
  int bond[SEP_BOND];   /**< Index of bonded particles */
  //  double lb[SEP_BOND];  /**< Bond lengths */

  double sigma;         /**< Hardsphere diameter */
  int *collid;          /**< List of collision partners */ 
  double *colltime;     /**< List of collisions times */ 

  double ldiff;          /**< Langevin diff */

  double xtrue[3];       /**< The position without boundary wrapping */    

  double x0[3];         /**< Initial positions */    
  double xp[3];         /**< Previous positions */
  double xv[3];         /**< Virtual positions (for parallisation) */
  double xn[3];         /**< Position at last neighborlist update */
  double xdot3[3];      /**< Third order position derivative */
  double xdot4[3];      /**< Fourth order position derivative */
  double xdot5[3];      /**< Fith order position derivative */

  double px[3];         /**< Predicted postion */
  double pv[3];         /**< Predicted velocity */
  double pa[3];         /**< Predicted acceleration */
  double pxdot3[3];     /**< Predicted third order derivative */
  double pxdot4[3];     /**< Predicted fourth order derivative */
  double pxdot5[3];     /**< Predicted fifth order derivative */  
						      			 
} seppart;

typedef seppart sepatom;


/**
 * Interaction structure - experimental
 */ 
typedef struct {
  char types[2];
  double cf;
  double (*fun)(double,char);
} sepinteraction;


typedef struct {

  unsigned num_mols;
  unsigned max_nuau;
	
  int flag_bonds, flag_angles, flag_dihedrals;

  unsigned num_bonds;    // Number of bonds
  unsigned *blist;       // (the two atom indicies + bond type)*num_bonds
  unsigned num_btypes;   // Number of bond types
   
  unsigned num_angles;    // Number of angles
  unsigned *alist;       // (the three atom indicies + angle type)*num_angles
  unsigned num_atypes;   // Number of angle types
  
  unsigned num_dihedrals; // Number of dihedrals
  unsigned *dlist;        // (the four atom indicies + dihedral type)*
                          // num_dihedrals
  unsigned num_dtypes;    // Number of diehdral types

  double *blengths;       // Bond length array
  double *angles;         // Angle array
  double *dihedrals;      // Dihedral array 

  unsigned flag_Fij;
  float ***Fij;           // Mol force-force array (dim. nmol x nmol x 3 ) - for pressure tensor
  float ***Fiajb;         // Force-force array (dim. npart x nmol x 3 ) - for couple tensor
} sepmolinfo;



/**
 * Defines the 3D system structure
 */
typedef struct {
  // System definition
  long int npart;       /**< Number of particles in system */
  double length[3];     /**< Container dimensions */
  double volume;        /**< Volume */ 
  
  // Integrator specifics
  int intgr_type;       /**< Integrator type */
  double dt;            /**< Integrator step */
  double tnow;          /**< Time now */ 
  unsigned ndof;        /**< Number of degrees of freedom */

  // Force stuff
  double cf;            /**< Maximum particle cut-off */  
  double lsubbox[3];    /**< Length of subboxes */ 
  int nsubbox[3];       /**< Number of subboxes */
  double skin;            /**< Skin...! */
  unsigned neighb_update;  // Neighbourlist update
  unsigned neighb_flag;    // 
  unsigned nupdate_neighb; // Number of nieghbourlist updates  
  
  unsigned omp_flag;

  // Molecular info - intra mol. forces
  sepmolinfo *molptr;

  sepinteraction *interactionptr;
  int numinteractions; //number of interactions defined

} sep3D;

typedef sep3D sepsys;

/**
 * Defines the sepmol structure 
 */
typedef struct {
  double m;              /**< Mass */ 
  double x[3], xtrue[3]; /**< Molecular cm - wrap + no wrap */
  double v[3];           /**< Molecular cm velocity */ 

  unsigned nuau;         /**< Number of United Atomic Units */   
  int *index;            /**< Indicies of constituting particles */  

  double ete[3];         /**< End-to-end vector */
  double re2;            /**< End-to-end distance squared */
  double rg;             /**< Ratio of gyration */
  double S[3];           /**< Orientation order parameter */

  double s[3];           /**< Intrinsic angular momentum */
  double inertia[3][3];  /**< Moment of inertia tensor */
  double w[3];           /**< Instrinsic angular velocity */
  int method_w;          /**< Method for determining w (intertia may be rank deficient) */
  double pel[3];         /**< Electrical dipole moment */
  
  char type;             /**< Molecules type */

  unsigned nbonds;       /**< For SHAKE */ 
  double *blength;       /**< For SHAKE */
  int shake_flag;        /**< For SHAKE */

} sepmol;


/**
 * Return structure
 */ 
typedef struct {
  double etot;
  double ekin, epot, ecoul;
  double sumv2;

  // Atomic pressure tensor
  double pot_P[3][3];
  double kin_P[3][3];
  double P[3][3];
  double p;

  // Molecular pressure tensor
  double pot_P_mol[3][3];
  double kin_P_mol[3][3];
  double P_mol[3][3];
  double p_mol;
  
  // Couple tensor
  double pot_T_mol[3][3];
  double kin_T_mol[3][3];
  double T_mol[3][3];
  double t_mol;

} sepret;

#endif
